﻿using ezCloud.Api.Common;
using ezCloud.Data;
using Microsoft.AspNet.Identity;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace ezCloud.Api.Controllers
{
    [Authorize]
    [RoutePrefix("api/Management")]
    public class ModulePaymentManagementController : ezController
    {
        public ModulePaymentManagementController()
        {
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("GetAllEzModules")]
        public async Task<IHttpActionResult> GetAllEzModules()
        {
            var user = Common.UserUtitily.getUserProfile();
            var allModules = context.EzModules.Where(ez => ez.EzModuleId == ez.EzModuleId).ToList();
            return Ok(allModules);
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("GetAllEzHotelModules")]
        public async Task<IHttpActionResult> GetAllEzHotelModules()
        {
            var user = Common.UserUtitily.getUserProfile();
            var allEzModules = context.EzModules.Where(ez => ez.EzModuleId == ez.EzModuleId).ToList();
            var allEzHotelModules = context.EzHotelModules.Where(ezh => ezh.HotelId == user.HotelId).ToList();
            return Ok(new
            {
                EzModules = allEzModules,
                EzHotelModules = allEzHotelModules
            });
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("GetAllManagementData")]
        public async Task<IHttpActionResult> GetAllManagementData()
        {
            var user = Common.UserUtitily.getUserProfile();
            var currentHotel = context.Hotels.Where(ht => ht.HotelId == user.HotelId).FirstOrDefault();
            var hotelRooms = currentHotel.RoomsList != null ? currentHotel.RoomsList.Where(r=>r.IsHidden== false).ToList().Count : 0;
            var defaultCurrency = context.Currencies.FirstOrDefault(curr => curr.Entity.ToLower() == "viet nam");
            var allHotelModules = context.EzModules.Where(ez => ez.EzModuleId == ez.EzModuleId && ez.Status == true).GroupJoin(context.EzHotelModules.Where(ezh => ezh.HotelId == user.HotelId),
                                 module => module.EzModuleId,
                                 hotelModule => hotelModule.EzModuleId,
                                 (module, hotelModule) => new
                                 {
                                     module,
                                     hotelModule,
                                     moduleDiscount = module.EzDefaultDiscountsList.FirstOrDefault().EzHotelDefaultDiscountsList.FirstOrDefault(dd => dd.HotelId == user.HotelId),
                                     moduleRangePrice = module.EzModuleRangerPricesList.Where(range => range.MinRoom <= hotelRooms && hotelRooms <= range.MaxRoom).FirstOrDefault()
                                 }).ToList();
            var paymentLogs = new List<EzPaymentLogs>();
            var hotelAccounts = new List<HotelAccountModel>();
            var logTemp = currentHotel.EzPaymentLogsList;//.Where(ezp => ezp.LogKey == "NEW_PAYMENT" && ezp.Status==0).ToList();
            if (logTemp.Count > 0)
            {
                paymentLogs.AddRange(logTemp);
            }


            var hotelAccountTemp = new HotelAccountModel
            {
                Hotel = currentHotel,
                Account = currentHotel.EzAccountsList.FirstOrDefault()
            };
            hotelAccounts.Add(hotelAccountTemp);
            var referralProgram = context.EzReferralPrograms.FirstOrDefault(rp => rp.Status == true);
            return Ok(new
            {
                allHotelModules,
                hotelRooms = hotelRooms,
                defaultCurrency,
                remainingDays = currentHotel.RemainingDays,
                PaymentLogs = paymentLogs.OrderByDescending(o => o.CreatedDate).ToList(),
                HotelAccounts = hotelAccounts,
                referralProgram = referralProgram
            });
        }

        public class HotelModuleModel
        {
            public List<EzHotelModules> hotelModule { get; set; }
            public EzModules module { get; set; }
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("UpdateModule")]
        public async Task<IHttpActionResult> UpdateModule(HotelModuleModel model)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var user = Common.UserUtitily.getUserProfile();

            if (model.hotelModule.FirstOrDefault().EzHotelModuleId != 0)
            {
                var currentHotelModule = context.EzHotelModules.Where(hm => hm.HotelId == user.HotelId && hm.EzHotelModuleId == model.hotelModule.FirstOrDefault().EzHotelModuleId).FirstOrDefault();
                currentHotelModule.Status = model.hotelModule.FirstOrDefault().Status;
                EzHotelModuleLogs hotelModuleLog = new EzHotelModuleLogs();
                hotelModuleLog.EzHotelModuleId = currentHotelModule.EzHotelModuleId;
                hotelModuleLog.Status = currentHotelModule.Status;
                hotelModuleLog.CreateDate = DateTime.UtcNow;
                context.EzHotelModuleLogs.InsertOnSubmit(hotelModuleLog);
                //context.SubmitChanges();
                //Common.Elastic.IndexLastAudit(context);
            }
            else
            {
                EzHotelModules hotelModule = new EzHotelModules();
                hotelModule.HotelId = user.HotelId;
                hotelModule.Status = true;
                hotelModule.EzModuleId = model.module.EzModuleId;
                context.EzHotelModules.InsertOnSubmit(hotelModule);
                //context.SubmitChanges();
                //Common.Elastic.IndexLastAudit(context);
                EzHotelModuleLogs hotelModuleLog = new EzHotelModuleLogs();
                hotelModuleLog.EzHotelModules = hotelModule;
                hotelModuleLog.Status = hotelModule.Status;
                hotelModuleLog.CreateDate = DateTime.UtcNow;
                context.EzHotelModuleLogs.InsertOnSubmit(hotelModuleLog);
                
            }

            if (model.module.ModuleCode == "CMSTAAH" && model.hotelModule.FirstOrDefault().Status == false)
            {
                CMConfigurations oldCMConfig = context.CMConfigurations.Where(cm => cm.HotelId == user.HotelId).FirstOrDefault();
                if (oldCMConfig != null)
                {
                    var cmModel = new
                    {
                        callback_url = "http://localhost/api/hotelbooking",
                        hotel_id = user.HotelId,
                        password = oldCMConfig.CMPassword,
                        staah_hotel_id = oldCMConfig.CMPropertyId,
                        staah_service_url = oldCMConfig.CMServiceUrl,
                        username = oldCMConfig.CMUser
                    };
                    using (var client = new HttpClient())
                    {
                        client.BaseAddress = new Uri(ConfigurationManager.AppSettings["ChannelManagerUrl"]);
                        client.DefaultRequestHeaders.Accept.Clear();
                        client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
                        HttpResponseMessage response = await client.PostAsJsonAsync("deregister", cmModel);
                        System.Diagnostics.Debug.WriteLine(response);
                        if (response.IsSuccessStatusCode)
                        {

                            context.CMConfigurations.DeleteOnSubmit(oldCMConfig);
                            //context.SubmitChanges();
                            //return Ok();
                        }
                        //return BadRequest("CAN_NOT_REGISTER_HOTEL_TO_CHANNEL_MANAGER");
                    }
                }
                
            }
            if (model.module.ModuleCode == "POS")
            {
                var POSConfig = context.POSConfigs.Where(p => p.HotelId == user.HotelId).FirstOrDefault();
                if (POSConfig==null)
                {
                    POSConfigs newPosConfig = new POSConfigs();
                    newPosConfig.HotelId = user.HotelId;
                    newPosConfig.InvoiceType = "A4";
                    newPosConfig.NumberOfDateToRemoveDrafBill = 30;
                    context.POSConfigs.InsertOnSubmit(newPosConfig);
                }
            }

            context.SubmitChanges();
            Common.Elastic.IndexLastAudit(context);

            return Ok();
        }

        public class Test
        {
            public EzHotelModules hotelModule { get; set; }
            public IEnumerable<EzDefaultDiscounts> discount { get; set; }

            public Test()
            {
            }
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("TestAudit")]
        public IHttpActionResult TestAudit()
        {
            //var nightAudit = new NightAudit();
            //NightAudit.PaymentAuditScheduler();
            //return Ok();
            var context = new ezCloudDataContext();
            var allActiveHotels = context.Hotels.Where(hotel => hotel.IsActive).ToList();
            foreach (var hotel in allActiveHotels)
            {
                //System.Diagnostics.Debug.WriteLine(hotel.HotelId);
                //if ((hotel.LastPaymentAuditDate != null &&
                //     ((DateTime) hotel.LastPaymentAuditDate).AddMinutes(hotel.TimeZoneOffset) >=
                //     DateTime.UtcNow.AddMinutes(hotel.TimeZoneOffset).Date) ||
                //    new TimeSpan(0, 0, 0) >= DateTime.UtcNow.AddMinutes(hotel.TimeZoneOffset).Subtract(DateTime.Today))
                //    continue;
                var ezAccount = context.EzAccounts.FirstOrDefault(acc => acc.HotelId == hotel.HotelId);
                if (ezAccount == null)
                    continue;
                var numberOfHotelDiscount = 0;
                hotel.LastPaymentAuditDate = DateTime.UtcNow;
                var hotelModuleDiscount =
                    context.EzHotelModules.Where(hotelModule => hotelModule.HotelId == hotel.HotelId)
                        .GroupJoin(
                            context.EzHotelDefaultDiscounts.Where(
                                hotelDiscount =>
                                    hotelDiscount.HotelId == hotel.HotelId &&
                                    hotelDiscount.StartDate.Value.Date <= DateTime.UtcNow.Date &&
                                    DateTime.UtcNow.Date <= hotelDiscount.EndDate.Value.Date),
                            hotelModule => hotelModule.EzModules.EzModuleId,
                            hotelDiscount => hotelDiscount.EzDefaultDiscounts.EzModuleId,
                            (hotelModule, hotelDiscount) => new
                            {
                                hotelModule,
                                hotelDiscount,
                                Module = hotelModule.EzModules
                            }).ToList();

                System.Diagnostics.Debug.WriteLine("HOTEL MODULE", hotelModuleDiscount);
                if (hotelModuleDiscount.Count > 0)
                {
                    var totalRooms =
                                hotel.RoomsList.Where(rm => rm.HotelId == hotel.HotelId && rm.IsHidden == false)
                                    .ToList()
                                    .Count;
                    foreach (var module in hotelModuleDiscount)
                    {
                        if (module.hotelDiscount.Any())
                        {
                            numberOfHotelDiscount = numberOfHotelDiscount + 1;
                            var paymentLogs = new EzPaymentLogs
                            {
                                EzHotelModuleId = module.hotelModule.EzHotelModuleId,
                                HotelId = hotel.HotelId,
                                CreatedDate = DateTime.UtcNow,
                                CreatedUserId = null,
                                LogKey = "DAILY_FEE",
                                Amount = 0.00M,
                                AmountFee = 0.00M,
                                Description =
                                    "Phí theo ngày - Module: " + module.Module.ModuleName + " - Tổng: 0 VND"
                            };
                            context.EzPaymentLogs.InsertOnSubmit(paymentLogs);
                        }
                        else if (ezAccount.Amount + ezAccount.AmountFee > 0)
                        {
                            var temp =
                                module.hotelModule.EzHotelModuleLogsList.Where(
                                    log => hotel.LastPaymentAuditDate != null && (log.CreateDate != null &&
                                                                                  log.CreateDate.Value.Date ==
                                                                                  hotel.LastPaymentAuditDate.Value.Date
                                                                                      .AddDays(-1)))
                                    .ToList();
                            if (temp.Count != 0 && (temp.Count <= 0 || temp.All(tmp => tmp.Status != true)))
                                continue;

                            //var temp =
                            //    module.hotelModule.EzHotelModuleLogsList.Where(
                            //        log => hotel.LastPaymentAuditDate != null)
                            //        .ToList();
                            if (temp.Count != 0 && (temp.Count <= 0 || temp.All(tmp => tmp.Status != true)))
                                continue;
                            var paymentLogs = new EzPaymentLogs
                            {
                                EzHotelModuleId = module.hotelModule.EzHotelModuleId,
                                HotelId = hotel.HotelId,
                                CreatedDate = DateTime.UtcNow,
                                CreatedUserId = null,
                                LogKey = "DAILY_FEE"
                            };



                            var moduleRangePrice = module.Module.EzModuleRangerPricesList.FirstOrDefault(range => range.EzModuleId == module.Module.EzModuleId && range.MinRoom <= totalRooms && totalRooms <= range.MaxRoom);
                            if (moduleRangePrice == null)
                                continue;
                            var totalModuleAmount = moduleRangePrice.AmountPerDay;

                            //if (module.Module.Unit == "ROOM")
                            //{
                            //    totalModuleAmount = totalModuleAmount * totalRooms;
                            //}

                            var amountTemp = ezAccount.AmountFee - totalModuleAmount;
                            if (amountTemp >= 0)
                            {
                                paymentLogs.AmountFee = module.Module.Amount;
                                paymentLogs.Amount = 0;
                                ezAccount.AmountFee = ezAccount.AmountFee - totalModuleAmount;
                            }
                            else
                            {
                                paymentLogs.AmountFee = ezAccount.AmountFee;
                                paymentLogs.Amount = -amountTemp;
                                ezAccount.AmountFee = 0.00M;
                                ezAccount.Amount = ezAccount.Amount - paymentLogs.Amount;
                            }
                            if (module.Module.Unit == "ROOM")
                            {
                                paymentLogs.Description = "Phí theo ngày - Module: " + module.Module.ModuleName +
                                                          " - Tổng: " +
                                                          Convert.ToDecimal(totalModuleAmount / totalRooms)
                                                              .ToString("0,0", CultureInfo.InvariantCulture) + " x " +
                                                          totalRooms + " = " +
                                                          Convert.ToDecimal(totalModuleAmount)
                                                              .ToString("0,0", CultureInfo.InvariantCulture) + " VND";
                            }
                            else
                            {
                                paymentLogs.Description = "Phí theo ngày - Module: " + module.Module.ModuleName +
                                                          " - Tổng: " +
                                                          Convert.ToDecimal(totalModuleAmount)
                                                              .ToString("0,0", CultureInfo.InvariantCulture) + " VND";
                            }

                            context.EzPaymentLogs.InsertOnSubmit(paymentLogs);
                        }
                    }
                }

                if (ezAccount.Amount + ezAccount.AmountFee <= 0)
                {
                    // Check if hotel had any free module
                    if (numberOfHotelDiscount == 0)
                    {
                        var auditLogs = new EzHotelAuditLogs
                        {
                            HotelId = hotel.HotelId,
                            OutOfServiceDate = DateTime.UtcNow
                        };
                        context.EzHotelAuditLogs.InsertOnSubmit(auditLogs);
                        //hotel.IsActive = false;
                    }
                }
                context.SubmitChanges();
                Elastic.IndexLastAudit(context);
            }
            return Ok();
        }

        public class HotelAccountModel
        {
            public Hotels Hotel { get; set; }
            public EzAccounts Account { get; set; }
        }

        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
        [Route("PaymentLogs")]
        public async Task<IHttpActionResult> PaymentLogs()
        {
            var user = Common.UserUtitily.getUserProfile();
            var paymentLogs = new List<EzPaymentLogs>();
            var hotelAccounts = new List<HotelAccountModel>();
            var logTemp = context.EzPaymentLogs.Where(paymentLog => paymentLog.HotelId == user.HotelId).ToList();
            var hotelItem = context.Hotels.Where(h => h.HotelId == user.HotelId).FirstOrDefault();
            if (logTemp.Count > 0)
            {
                paymentLogs.AddRange(logTemp);
            }
            var hotelAccountTemp = new HotelAccountModel
            {
                Hotel = hotelItem,
                Account = hotelItem.EzAccountsList.FirstOrDefault()
            };
            hotelAccounts.Add(hotelAccountTemp);
            return Ok(new
            {
                PaymentLogs = paymentLogs.OrderByDescending(o => o.CreatedDate).ToList(),
                HotelAccounts = hotelAccounts
            });
        }

        //public 
    }
}